package com.niiwoo.civet.mobile.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.account.dto.common.PayChannelDTO;
import com.niiwoo.civet.account.dto.request.RechargeAccountTypeRequestDTO;
import com.niiwoo.civet.account.dto.request.RechargeDubboRequestDTO;
import com.niiwoo.civet.account.dto.request.RechargeRecordRequestDTO;
import com.niiwoo.civet.account.dto.response.*;
import com.niiwoo.civet.account.enums.RechargeBusinessTypeEnum;
import com.niiwoo.civet.account.enums.StatusEnum;
import com.niiwoo.civet.account.service.AccountDubboService;
import com.niiwoo.civet.account.service.PayChannelBankDubboService;
import com.niiwoo.civet.account.service.bankcard.BankCardDubboService;
import com.niiwoo.civet.account.service.recharge.RechargeDubboService;
import com.niiwoo.civet.base.constant.OrgConstant;
import com.niiwoo.civet.mobile.util.R360RedisService;
import com.niiwoo.civet.mobile.vo.common.FormVO;
import com.niiwoo.civet.mobile.vo.common.UserAccountForThirdVO;
import com.niiwoo.civet.mobile.vo.common.UserAccountVO;
import com.niiwoo.civet.mobile.vo.request.recharge.*;
import com.niiwoo.civet.mobile.vo.response.recharge.*;
import com.niiwoo.civet.trade.dto.response.kaola.KaoLaLiCaiImmediateRepayResponseDTO;
import com.niiwoo.civet.trade.service.koala.KaoLaLiCaiDubboService;
import com.niiwoo.civet.trade.service.project.ProjectDubboService;
import com.niiwoo.civet.user.dto.response.UserBasicInfoResponseDTO;
import com.niiwoo.civet.user.enums.UserForbidTypeEnum;
import com.niiwoo.civet.user.service.OrganizationDubboService;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.civet.user.service.UserForbidDubboService;
import com.niiwoo.tripod.lanmao.enums.BankCodeEnum;
import com.niiwoo.tripod.lanmao.enums.PayCompanyEnum;
import com.niiwoo.tripod.lanmao.enums.UserRoleEnum;
import com.niiwoo.tripod.provider.dto.response.PageResponseDTO;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.web.annotation.AuthIgnore;
import com.niiwoo.tripod.web.util.PrincipalContext;
import com.niiwoo.tripod.web.vo.PageResponseVO;
import com.niiwoo.tripod.web.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * Created by wangjichao on 2017/10/16.
 */
@RestController
@RequestMapping("/recharge")
@Api(tags = "充值（肖应平、肖耀才）", description = "/recharge")
@Slf4j
public class RechargeController {

    @Autowired
    private R360RedisService r360RedisService;

    @Reference(version = "1.0.0")
    private RechargeDubboService rechargeDubboService;
    @Reference(version = "1.0.0")
    private UserForbidDubboService userForbidDubboService;
    @Reference(version = "1.0.0")
    private KaoLaLiCaiDubboService kaoLaLiCaiDubboService;
    @Reference(version = "1.0.0")
    private OrganizationDubboService organizationDubboService;
    @Reference(version = "1.0.0")
    private UserBasicInfoDubboService userBasicInfoDubboService;
    @Reference(version = "1.0.0")
    private AccountDubboService accountDubboService;
    @Reference(version = "1.0.0")
    private BankCardDubboService bankCardDubboService;
    @Reference(version = "1.0.0")
    private PayChannelBankDubboService payChannelBankDubboService;
    @Reference(version = "1.0.0")
    private ProjectDubboService projectDubboService;



    @PostMapping("/projectOning/third")
    @ApiOperation("考拉在进行中的标的(第三方)")
    @AuthIgnore
    public Result<ProjectBankVO> projectBankForThird(@RequestBody ThirdRechargeRequestVO thirdRechargeRequestVO) {
        String userId = validThirdToken(thirdRechargeRequestVO);
        return doProjectBank(userId);
    }

    @PostMapping("/projectOning")
    @ApiOperation("考拉在进行中的标的")
    public Result<ProjectBankVO> projectBank() {
        String userId = PrincipalContext.getUserId();
        return doProjectBank(userId);
    }

    private Result<ProjectBankVO> doProjectBank(String userId){
        KaoLaLiCaiImmediateRepayResponseDTO kaoLaLiCaiImmediateRepayResponseDTO = kaoLaLiCaiDubboService.getRepayingProjectByUserId(userId);
        log.info("考拉在进行中的标的{}", JSONObject.toJSONString(kaoLaLiCaiImmediateRepayResponseDTO));
        ProjectBankVO projectBankVO = null;
        if (kaoLaLiCaiImmediateRepayResponseDTO != null) {
            projectBankVO = new ProjectBankVO();
            projectBankVO.setProjectId(kaoLaLiCaiImmediateRepayResponseDTO.getProjectId());
            projectBankVO.setAmount(kaoLaLiCaiImmediateRepayResponseDTO.getAmount());
            projectBankVO.setBankCard(kaoLaLiCaiImmediateRepayResponseDTO.getBankCard());
        }
        return Result.with(projectBankVO);
    }

    @PostMapping("/getRechargeForm/third")
    @ApiOperation("获取充值表单(第三方)")
    @AuthIgnore
    public Result<GetRechargeFormResponseVO> getRechargeFormForThird(@RequestBody @Valid RechargeWebVO rechargeWebVO) throws ParseException{
        log.info("获取充值表单getRechargeFormForThird{}", JSONObject.toJSONString(rechargeWebVO));
        String userId = validThirdToken(rechargeWebVO.getRequestVO());

        return doGetRechargeForm(userId,rechargeWebVO);
    }

    @PostMapping("/getRechargeForm")
    @ApiOperation("获取充值表单")
    public Result<GetRechargeFormResponseVO> getRechargeForm(@RequestBody @Valid RechargeWebVO rechargeWebVO) throws ParseException {
        log.info("获取充值表单getRechargeForm{}", JSONObject.toJSONString(rechargeWebVO));
        String userId = PrincipalContext.getUserId();
        return doGetRechargeForm(userId,rechargeWebVO);
    }

    private Result<GetRechargeFormResponseVO> doGetRechargeForm(String userId,RechargeWebVO rechargeWebVO) throws ParseException{
        //用户行为禁止判断
        userForbidDubboService.validUserForbidInfo(userId, UserForbidTypeEnum.RECHARGE);

        // 机构ID
        String orgId;
        ThirdRechargeRequestVO requestVO = rechargeWebVO.getRequestVO();
        if(rechargeWebVO.getRequestVO() != null && Objects.equals(R360RedisService.ThirdPart.ORG.getChannel(), requestVO.getChannel())) {
            orgId = organizationDubboService.loadValidOrgId(requestVO.getOrgCode());
        }else{
            orgId = OrgConstant.NIIWOO_ORG_ID;
        }

        //封装处理业务的dto
        RechargeDubboRequestDTO rechargeDubboRequestDTO = new RechargeDubboRequestDTO();
        rechargeDubboRequestDTO.setAmount(rechargeWebVO.getAmount());
        rechargeDubboRequestDTO.setRedirectUrl(rechargeWebVO.getRedirectUrl());
        rechargeDubboRequestDTO.setPayChannelCode(rechargeWebVO.getPayChannelCode());
        rechargeDubboRequestDTO.setBankCode(BankCodeEnum.enumOf(rechargeWebVO.getBankCode()));
        rechargeDubboRequestDTO.setUserId(userId);
        rechargeDubboRequestDTO.setBusinessType(rechargeWebVO.getBusinessType());
        rechargeDubboRequestDTO.setRole(UserRoleEnum.enumOf(rechargeWebVO.getAccountRole()));
        rechargeDubboRequestDTO.setOrgId(orgId);
        //调用dubbo服务
        RechargeResponseDTO responseDTO = rechargeDubboService.structureParams(rechargeDubboRequestDTO);
        if (responseDTO == null) {
            throw new BizException("ACC40006");
        }
        //定义并封装要返回给前端的vo
        GetRechargeFormResponseVO getRechargeFormResponseVO = new GetRechargeFormResponseVO();
        FormVO formVO = new FormVO();
        formVO.setAction(responseDTO.getAction());
        formVO.setParams(responseDTO.getParams());
        getRechargeFormResponseVO.setForm(formVO);
        return Result.with(getRechargeFormResponseVO);
    }

    @PostMapping("/rechargeRecordList/third")
    @ApiOperation("充值记录列表查询(第三方)")
    @AuthIgnore
    public Result<RechargeRecordRespVO> rechargeRecordListForThird(@RequestBody @Valid RechargeListRequestVO rechargeListRequestVO){
        String userId = validThirdToken(rechargeListRequestVO.getRequestVO());
        return doRechargeRecordList(userId,rechargeListRequestVO);
    }

    @PostMapping("/rechargeRecordList")
    @ApiOperation("充值记录列表查询")
    public Result<RechargeRecordRespVO> rechargeRecordList(@RequestBody @Valid RechargeListRequestVO rechargeListRequestVO) {
        String userId = PrincipalContext.getUserId();
        return doRechargeRecordList(userId,rechargeListRequestVO);
    }

    private Result<RechargeRecordRespVO> doRechargeRecordList(String userId,RechargeListRequestVO rechargeListRequestVO){
        RechargeRecordRespVO rechargeRecordRespVO = new RechargeRecordRespVO();
        BigDecimal totalAmount = BigDecimal.ZERO;
        //定义要返回给前端的vo
        PageResponseVO<RechargeRecordVO> pageResponseVO = new PageResponseVO<>();
        List<RechargeRecordVO> recordVOS = new ArrayList<>();
        //封装处理业务的dto
        RechargeRecordRequestDTO listRequestDTO = new RechargeRecordRequestDTO();
        listRequestDTO.setPageNumber(rechargeListRequestVO.getPageNumber());
        listRequestDTO.setPageSize(rechargeListRequestVO.getPageSize());
        listRequestDTO.setUserId(userId);
        listRequestDTO.setStatus(rechargeListRequestVO.getStatus());
        listRequestDTO.setStartDate(rechargeListRequestVO.getStartDate());
        listRequestDTO.setEndDate(rechargeListRequestVO.getEndDate());
        // 机构ID
        String orgId;
        ThirdRechargeRequestVO requestVO = rechargeListRequestVO.getRequestVO();
        if(rechargeListRequestVO.getRequestVO() != null && Objects.equals(R360RedisService.ThirdPart.ORG.getChannel(), requestVO.getChannel())) {
            orgId = organizationDubboService.loadValidOrgId(requestVO.getOrgCode());
        }else if( null != rechargeListRequestVO.getOrgId() && !"".equals(rechargeListRequestVO.getOrgId())){
            orgId = rechargeListRequestVO.getOrgId();
        }else{
            orgId = OrgConstant.NIIWOO_ORG_ID;
        }
        listRequestDTO.setOrgId(orgId);

        //调用dubbo服务
        PageResponseDTO<RechargeRecordResponseDTO> responseDTO = rechargeDubboService.rechargeRecordList(listRequestDTO);
        log.info("user = {},充值请求列表{}",userId,JSONObject.toJSONString(responseDTO));
        //封装要返回给前端的vo
        for (RechargeRecordResponseDTO dto : responseDTO.getItems()) {
            RechargeRecordVO rechargeRecordVO = new RechargeRecordVO();
            rechargeRecordVO.setAmount(dto.getAmount());
            rechargeRecordVO.setStatus(dto.getStatus());
            rechargeRecordVO.setTime(dto.getTime());
            rechargeRecordVO.setAccountRole(dto.getAccountRole());
            recordVOS.add(rechargeRecordVO);
            if (StatusEnum.SUCCESS.getValue() == dto.getStatus()) {
                totalAmount = totalAmount.add(dto.getAmount());
            }
        }
        pageResponseVO.setItems(recordVOS);
        pageResponseVO.setTotalCount(responseDTO.getTotalCount());
        pageResponseVO.setTotalPage(responseDTO.getTotalPage());
        rechargeRecordRespVO.setPageResponseVO(pageResponseVO);
        rechargeRecordRespVO.setTotalAmount(totalAmount);
        rechargeRecordRespVO.setServerDate(new Date());
        return Result.with(rechargeRecordRespVO);
    }

    @PostMapping("/queryUserSuccRecharge/third")
    @ApiOperation("查询用户累计成功充值金额(第三方)")
    @AuthIgnore
    public Result<JSONObject> queryUserSuccRechargeForThird(@RequestBody ThirdRechargeRequestVO thirdRechargeRequestVO){
        String userId = validThirdToken(thirdRechargeRequestVO);
        String orgId = organizationDubboService.loadValidOrgId(thirdRechargeRequestVO.getOrgCode());
        return doQueryUserSuccRecharge(userId,orgId);
    }

    @PostMapping("/queryUserSuccRecharge")
    @ApiOperation("查询用户累计成功充值金额")
    public Result<JSONObject> queryUserSuccRecharge(){
        String userId = PrincipalContext.getUserId();
        return doQueryUserSuccRecharge(userId,OrgConstant.NIIWOO_ORG_ID);
    }

    private Result<JSONObject> doQueryUserSuccRecharge(String userId,String orgId){
        BigDecimal totalAmount = rechargeDubboService.queryUserTotalRechrageAmountWithOrgId(userId,orgId);
        JSONObject jsonObject = new JSONObject();
        if (null == totalAmount) {
            totalAmount = new BigDecimal(0.0);
        }
        jsonObject.put("totalAmount", totalAmount);
        return Result.with(jsonObject);
    }

    @PostMapping("/queryUserAccountInfo/third")
    @ApiOperation("用户账户类型与余额(第三方)")
    @AuthIgnore
    public Result<UserAccountForThirdVO> queryUserAccountInfoForThird(@RequestBody ThirdRechargeRequestVO thirdRechargeRequestVO){
        log.info("queryUserAccountInfoForThird request:{}", JSON.toJSONString(thirdRechargeRequestVO));
        String userId = validThirdToken(thirdRechargeRequestVO);
        String orgId = organizationDubboService.loadValidOrgId(thirdRechargeRequestVO.getOrgCode());

        UserBasicInfoResponseDTO userBasicInfoResponseDTO = userBasicInfoDubboService.getUserBasicInfo(userId);
        List<UserAccountVO> userAccountVOList =  doQueryUserAccountInfo(userId,orgId);

        UserAccountForThirdVO userAccountForThirdVO = new UserAccountForThirdVO();
        userAccountForThirdVO.setMobile(userBasicInfoResponseDTO.getMobileNo());
        userAccountForThirdVO.setAccountList(userAccountVOList);
        return Result.with(userAccountForThirdVO);
    }

    @PostMapping("/queryUserAccountInfo")
    @ApiOperation("用户账户类型与余额")
    public Result<List<UserAccountVO>> queryUserAccountInfo() {
        String userId = PrincipalContext.getUserId();
        List<UserAccountVO> userAccountVOList = doQueryUserAccountInfo(userId,OrgConstant.NIIWOO_ORG_ID);
        return Result.with(userAccountVOList);
    }

    private List<UserAccountVO> doQueryUserAccountInfo(String userId,String orgId){
        List<AccountAmountDTO> amountDTOList = rechargeDubboService.queryUserAccountInfoWithOrgId(userId,orgId);
        List<UserAccountVO> userAccountVOS = new ArrayList<>();
        if (!amountDTOList.isEmpty()) {
            amountDTOList.forEach(p -> {
                UserAccountVO userAccountVO = new UserAccountVO();
                userAccountVO.setAccountId(p.getAccountId());
                userAccountVO.setAccountNo(p.getAccountNo());
                userAccountVO.setAccountRole(p.getAccountRole());
                userAccountVO.setActiveAccount(p.getActiveAccount());
                userAccountVO.setAvailableAmount(p.getAvailableAmount());
                userAccountVOS.add(userAccountVO);
            });
        }
        return userAccountVOS;
    }

    @PostMapping("/bankCardTypeLimit/third")
    @ApiOperation("银行卡类型与限额(第三方)")
    @AuthIgnore
    public Result<UserBankCardLimitVO> bankCardTypeLimitForThird(@RequestBody ThirdRechargeRequestVO thirdRechargeRequestVO){
        String userId = validThirdToken(thirdRechargeRequestVO);
        String orgId = organizationDubboService.loadValidOrgId(thirdRechargeRequestVO.getOrgCode());
        return doBankTypeLimit(userId,orgId);
    }

    @PostMapping("/bankCardTypeLimit")
    @ApiOperation("银行卡类型与限额")
    public Result<UserBankCardLimitVO> bankCardTypeLimit() {
        String userId = PrincipalContext.getUserId();
        return doBankTypeLimit(userId,OrgConstant.NIIWOO_ORG_ID);
    }

    private Result<UserBankCardLimitVO> doBankTypeLimit(String userId,String orgId){
        UserBankInfoResponseDTO userBankInfoResponseDTO = rechargeDubboService.queryUserBankInfoWithOrgId(userId,orgId);
        UserBankCardLimitVO userBankCardLimitVO = null;
        if (userBankInfoResponseDTO != null) {
            userBankCardLimitVO = new UserBankCardLimitVO();
            userBankCardLimitVO.setBankCardType(userBankInfoResponseDTO.getBankCardType());
            userBankCardLimitVO.setBankCode(userBankInfoResponseDTO.getBankCode());
            userBankCardLimitVO.setEachLimitAmount(userBankInfoResponseDTO.getEachLimitAmount());
            userBankCardLimitVO.setEndNum(userBankInfoResponseDTO.getEndNum());
            userBankCardLimitVO.setMonthlyLimitAmount(userBankInfoResponseDTO.getMonthlyLimitAmount());
            userBankCardLimitVO.setPayChannelCode(userBankInfoResponseDTO.getPayChannelCode());
        }
        return Result.with(userBankCardLimitVO);
    }

    @PostMapping("/userRechrageSuccRecord/third")
    @ApiOperation("用户最近的成功充值记录(第三方)")
    @AuthIgnore
    public Result<RechargeLatelyRecoVO> userRechrageSuccRecordForThird(@RequestBody ThirdRechargeRequestVO thirdRechargeRequestVO){
        String userId = validThirdToken(thirdRechargeRequestVO);
        String orgId = organizationDubboService.loadValidOrgId(thirdRechargeRequestVO.getOrgCode());
        return doUserRechargeSuccRecord(userId,orgId);
    }

    @PostMapping("/userRechrageSuccRecord")
    @ApiOperation("用户最近的成功充值记录")
    public Result<RechargeLatelyRecoVO> userRechrageSuccRecord() {
        String userId = PrincipalContext.getUserId();
        return doUserRechargeSuccRecord(userId, OrgConstant.NIIWOO_ORG_ID);
    }

    private Result<RechargeLatelyRecoVO> doUserRechargeSuccRecord(String userId,String orgId){
        RechargeOrderDTO rechargeOrderDTO = rechargeDubboService.userRechrageSuccRecordWithOrgId(userId,orgId);
        RechargeLatelyRecoVO rechargeLatelyRecoVO = null;
        if (rechargeOrderDTO != null) {
            rechargeLatelyRecoVO = new RechargeLatelyRecoVO();
            rechargeLatelyRecoVO.setAccountId(rechargeOrderDTO.getAccountId());
            rechargeLatelyRecoVO.setAccountRole(rechargeOrderDTO.getAccountRole());
            rechargeLatelyRecoVO.setAmount(rechargeOrderDTO.getAmount());
            rechargeLatelyRecoVO.setRequestNo(rechargeOrderDTO.getRequestNo());
            rechargeLatelyRecoVO.setUserId(rechargeOrderDTO.getUserId());

        }
        return Result.with(rechargeLatelyRecoVO);
    }

    @PostMapping("/recharge")
    @ApiOperation("大额网银充值")
    public Result<GetRechargeFormResponseVO> recharge(@RequestBody @Valid RechargeWebPayVO rechargeWebVO) {
        log.info("method:recharge request:{}", JSON.toJSONString(rechargeWebVO));
        String userId = PrincipalContext.getUserId();

        return this.commonWebRecharge(userId, OrgConstant.NIIWOO_ORG_ID, rechargeWebVO);
    }


    @PostMapping("/recharge/third")
    @ApiOperation("第三方大额网银充值")
    @AuthIgnore
    public Result<GetRechargeFormResponseVO> rechargeForThird(@RequestBody @Valid RechargeWebPayVO rechargeWebVO) {
        log.info("method:rechargeForThird request:{}", JSON.toJSONString(rechargeWebVO));
        String userId = validThirdToken(rechargeWebVO.getRequestVO());
        String orgId = organizationDubboService.loadValidOrgId(rechargeWebVO.getRequestVO().getOrgCode());

        return this.commonWebRecharge(userId, orgId, rechargeWebVO);
    }

    private Result<GetRechargeFormResponseVO> commonWebRecharge(String userId, String orgId, RechargeWebPayVO rechargeWebVO) {
        log.info("commonWebRecharge userId:{}, orgId:{}, rechargeWebVO:{}", userId, orgId, JSON.toJSONString(rechargeWebVO));
        //判断是否禁止用户提现
        userForbidDubboService.validUserForbidInfo(userId, UserForbidTypeEnum.RECHARGE);

        //组装调用dubbo接口的参数
        RechargeDubboRequestDTO rechargeDubboRequestDTO = new RechargeDubboRequestDTO();
        rechargeDubboRequestDTO.setUserId(userId);
        rechargeDubboRequestDTO.setRole(UserRoleEnum.enumOf(rechargeWebVO.getAccountRole()));
        rechargeDubboRequestDTO.setOrgId(orgId);
        rechargeDubboRequestDTO.setAmount(rechargeWebVO.getAmount());
        rechargeDubboRequestDTO.setRedirectUrl(rechargeWebVO.getRedirectUrl());
        rechargeDubboRequestDTO.setBusinessType(rechargeWebVO.getBusinessType());
        //充值渠道默认为宝付，即使前端“payChannelCode”参数有传值
        rechargeDubboRequestDTO.setPayChannelCode(PayCompanyEnum.BAOFOO.getCode());
        if(rechargeDubboRequestDTO.getBusinessType().equals(RechargeBusinessTypeEnum.ENTERPRISE.getValue())){
            //企业充值可以在页面上选择充值渠道
            rechargeDubboRequestDTO.setPayChannelCode(rechargeWebVO.getPayChannelCode());
        }

        //调用dubbo服务(以前只有平台可以网银充值，后来开放给对个人和企业，但是方法名不变)
        RechargeResponseDTO responseDTO = rechargeDubboService.platformRecharge(rechargeDubboRequestDTO);
        //定义并封装要返回给前端的vo
        GetRechargeFormResponseVO getRechargeFormResponseVO = new GetRechargeFormResponseVO();
        FormVO formVO = new FormVO();
        formVO.setAction(responseDTO.getAction());
        formVO.setParams(responseDTO.getParams());
        getRechargeFormResponseVO.setForm(formVO);
        return Result.with(getRechargeFormResponseVO);
    }

    @PostMapping("/rechargeEnable/third")
    @ApiOperation("是否支持充值(第三方)")
    @AuthIgnore
    public Result<RechargeEnableResponseVO> rechargeEnableForThird(@RequestBody ThirdRechargeRequestVO thirdRechargeRequestVO){
        String userId = validThirdToken(thirdRechargeRequestVO);
        String orgId = organizationDubboService.loadValidOrgId(thirdRechargeRequestVO.getOrgCode());
        return doRechargeEnable(userId,orgId);
    }

    @PostMapping("/rechargeEnable")
    @ApiOperation("是否支持充值")
    public Result<RechargeEnableResponseVO> rechargeEnable() {
    	String userId = PrincipalContext.getUserId();
        return doRechargeEnable(userId,OrgConstant.NIIWOO_ORG_ID);
    }

    private Result<RechargeEnableResponseVO> doRechargeEnable(String userId,String orgId){
        RechargeEnableResponse rechargeEnable = rechargeDubboService.rechargeEnableWithOrgId(userId,orgId);

        RechargeEnableResponseVO response = new RechargeEnableResponseVO();
        response.setRechargeEnable(rechargeEnable.getRechargeEnable());
        response.setRebindEnable(rechargeEnable.getRebindEnable());
        response.setRebindForbidReason(rechargeEnable.getRebindForbidReason());
        response.setBankCode(rechargeEnable.getBankCode());
        response.setBankName(rechargeEnable.getBankName());

        return Result.with(response);
    }

    /**
     * 验证第三方TOKEN
     *
     * @param requestVO
     * @return
     */
    private String validThirdToken(ThirdRechargeRequestVO requestVO){
        String userId;
        if (requestVO.getChannel() == null) {
            userId = r360RedisService.verifyTokenAndGetUserId(requestVO.getToken());
        } else {
            userId = r360RedisService.verifyTokenAndGetUserId(requestVO.getToken(), requestVO.getChannel());
        }
        return userId;
    }

    @PostMapping("/statisticsRecharge")
    @ApiOperation("充值金额统计")
    public Result<RechargeStatisticsResponseVO> statisticsRecharge(String orgId){
        RechargeStatisticsResponseVO responseVO = new RechargeStatisticsResponseVO();
        String userId = PrincipalContext.getUserId();
        RechargeStatisticsResponseDTO rechargeStatisticsResponseDTO = rechargeDubboService.statisticsCurrentRecharge(userId,orgId);
        BeanUtils.copyProperties(rechargeStatisticsResponseDTO,responseVO);
        return Result.with(responseVO);
    }

    @PostMapping("/queryLatelyRechargeAccountType/third")
    @ApiOperation("最近充值的账户类型/第三方")
    @AuthIgnore
    public Result<RechargeAccountResponseVO> queryLatelyRechargeAccountThird(@RequestBody ThirdRechargeRequestVO thirdRechargeRequestVO){
        String userId = validThirdToken(thirdRechargeRequestVO);
        String orgId = organizationDubboService.loadValidOrgId(thirdRechargeRequestVO.getOrgCode());
        return queryLatelyRechargeAccountSubject(userId,orgId);
    }

    @PostMapping("/queryLatelyRechargeAccountType")
    @ApiOperation("最近充值的账户类型")
    public Result<RechargeAccountResponseVO> queryLatelyRechargeAccount(){
        String userId = PrincipalContext.getUserId();
        return queryLatelyRechargeAccountSubject(userId,OrgConstant.NIIWOO_ORG_ID);
    }

    /**
     * 最近充值账户类型主体
     * @param userId
     * @return
     */
    private Result<RechargeAccountResponseVO> queryLatelyRechargeAccountSubject(String userId,String orgId){
        RechargeAccountResponseVO responseVO = new RechargeAccountResponseVO();

        List<RechargeAccountResponseVO.AccountTypeListVO> accountTypeListVOList = new ArrayList<>();
        List<AccountBaseResponse> accountBaseResponseList = accountDubboService.listNiiwooAccountByUserId(userId,orgId);
        if( null == accountBaseResponseList && accountBaseResponseList.size() == 0 ){
            throw new BizException("ACC10001");// 存管账户未开通
        }


        RechargeAccountTypeRequestDTO rechargeAccountTypeRequestDTO = new RechargeAccountTypeRequestDTO();
        rechargeAccountTypeRequestDTO.setUserId(userId);
        List<Long> accountIds = new ArrayList<>();

        int accountOpenStatus = 0 ; //账户开通状态 2 为投资账户，3为借款账户，5为都已开通
        for (AccountBaseResponse accountBaseResponse : accountBaseResponseList){
            RechargeAccountResponseVO.AccountTypeListVO accountTypeListVO = new RechargeAccountResponseVO().new AccountTypeListVO();
            accountTypeListVO.setAccountId(accountBaseResponse.getAccountId());
            accountTypeListVO.setAccountRole(accountBaseResponse.getAccountRole());
            accountTypeListVO.setIsActived(accountBaseResponse.getImportUserActiva());
            accountTypeListVO.setAvailableBalance(accountBaseResponse.getAvailableAmount());
            accountTypeListVOList.add(accountTypeListVO);
            accountOpenStatus = accountOpenStatus + accountBaseResponse.getAccountRole();
            accountIds.add(accountBaseResponse.getAccountId());
        }
        rechargeAccountTypeRequestDTO.setAccountIds(accountIds);

        RechargeAccountTypeDTO rechargeAccountTypeDTO = rechargeDubboService.queryLatelyRechargeAccountType(rechargeAccountTypeRequestDTO);
        if( null != rechargeAccountTypeDTO) {
            if(rechargeAccountTypeDTO.getAccountRole().toString().equals("-1")){
                responseVO.setLatelyRechargeAccountRole(accountBaseResponseList.get(0).getAccountRole());
            }else{
                responseVO.setLatelyRechargeAccountRole(rechargeAccountTypeDTO.getAccountRole());
            }

        }else{
            int count = projectDubboService.queryProjectCountByUserId(userId,orgId);
            if( count != 0 ){
                responseVO.setLatelyRechargeAccountRole(UserRoleEnum.BORROWERS.getValue());
            }else if(accountOpenStatus == 2 || accountOpenStatus == 5 ){
                responseVO.setLatelyRechargeAccountRole(UserRoleEnum.INVESTOR.getValue());
            }else{
                responseVO.setLatelyRechargeAccountRole(UserRoleEnum.BORROWERS.getValue());
            }
        }
        GetSimpleUserBankCardResponse getSimpleUserBankCardResponse = bankCardDubboService.getSimpleUserBankCard(userId,orgId);
        RechargeAccountResponseVO.BankCardInfo bankCardInfo = new RechargeAccountResponseVO().new BankCardInfo();
        RechargeAccountResponseVO.LimitRechargeReadme limitRechargeReadme = new RechargeAccountResponseVO().new LimitRechargeReadme();

        bankCardInfo.setBankAccountNo(getSimpleUserBankCardResponse.getBankCard().getBankAccountNo());
        bankCardInfo.setBankCode(getSimpleUserBankCardResponse.getBankCard().getBankType().getBankCode());
        bankCardInfo.setBankName(getSimpleUserBankCardResponse.getBankCard().getBankType().getBankName());
        bankCardInfo.setHasRebindApply(getSimpleUserBankCardResponse.isHasRebindApply());
        bankCardInfo.setBankTypeId(getSimpleUserBankCardResponse.getBankCard().getBankType().getBankTypeId());
        bankCardInfo.setChangeStatus(getSimpleUserBankCardResponse.getBankCard().getBankType().getRechargeChangeStatus());
        bankCardInfo.setIsMaintain(getSimpleUserBankCardResponse.getBankCard().getBankType().getIsMaintain());

        RechargeMoneyVerifyResponseDTO rechargeMoneyVerifyResponseDTO = rechargeDubboService.getStatisticsRechargeMoneyByUserId(rechargeAccountTypeRequestDTO);
        try{
            PayChannelDTO payChannelDTO = bankCardDubboService.getUserRechargeChannelByRoute(getSimpleUserBankCardResponse.getBankCard().getBankType().getBankTypeId(), userId);
            if( null != payChannelDTO){
                bankCardInfo.setPayChannelCode(payChannelDTO.getPayChannelCode());

                bankCardInfo.setDealMaxTrade(payChannelDTO.getMaxAmountPerTrade());
                bankCardInfo.setDayMaxTrade(payChannelDTO.getMaxAmountPerDay());
                bankCardInfo.setMonthMaxTrade(payChannelDTO.getMaxAmountPerMonth());

                BigDecimal daySurplusRecharge = payChannelDTO.getMaxAmountPerDay();
                BigDecimal monthSurplusRecharge = payChannelDTO.getMaxAmountPerMonth();

                // 暖心借 为了支持机构
                //BigDecimal daySurplusRecharge = payChannelDTO.getMaxAmountPerDay().subtract(rechargeMoneyVerifyResponseDTO.getDayTotalRechargeMoney());
                // monthSurplusRecharge = payChannelDTO.getMaxAmountPerMonth().subtract(rechargeMoneyVerifyResponseDTO.getMoneyTotalRechargeMoney());

                if(orgId.equals(OrgConstant.NIIWOO_ORG_ID)){
                    daySurplusRecharge = payChannelDTO.getMaxAmountPerDay().subtract(rechargeMoneyVerifyResponseDTO.getDayTotalRechargeMoney());
                    monthSurplusRecharge = payChannelDTO.getMaxAmountPerMonth().subtract(rechargeMoneyVerifyResponseDTO.getMoneyTotalRechargeMoney());
                }

                limitRechargeReadme.setDaySurplusMoney(daySurplusRecharge);
                limitRechargeReadme.setMonthSurplusMoney(monthSurplusRecharge);
                limitRechargeReadme.setSupperPay(Boolean.TRUE);
            }else{
                limitRechargeReadme.setSupperPay(Boolean.FALSE);
            }
        }catch(Exception e){
            log.error("没有找到支付渠道:userId={}",userId,e);
            limitRechargeReadme.setSupperPay(Boolean.FALSE);
        }

        responseVO.setLimitRechargeReadme(limitRechargeReadme);
        responseVO.setBankCardInfo(bankCardInfo);
        responseVO.setAccountTypeListVOList(accountTypeListVOList);

        if(accountBaseResponseList.size() == 1){
            //因为历史数据原因导致有人未开存管账户但却有借款记录，导致projectDubboService.queryProjectCountByUserId(userId,orgId)有值引起上面的判断有问题
            responseVO.setLatelyRechargeAccountRole(accountBaseResponseList.get(0).getAccountRole());
        }

        log.info("最近充值的账户类型:{}",JSON.toJSONString(responseVO));
        return Result.with(responseVO);
    }

    @PostMapping("/queryMaxRechargeAmount")
    @ApiOperation("校验充值金额")
    public Result<RechargeVerifyResponseVO> queryMaxRechargeAmount(@RequestBody RechargeVerifyRequestVO rechargeVerifyRequestVO){
        String userId = PrincipalContext.getUserId();
        return queryMaxRechargeAmountSubject(rechargeVerifyRequestVO,userId);
    }
    @PostMapping("/queryMaxRechargeAmount/third")
    @ApiOperation("校验充值金额/第三方")
    @AuthIgnore
    public Result<RechargeVerifyResponseVO> queryMaxRechargeAmountThird(@RequestBody RechargeVerifyRequestVO rechargeVerifyRequestVO){
        ThirdRechargeRequestVO thirdRechargeRequestVO = new ThirdRechargeRequestVO();
        thirdRechargeRequestVO.setChannel(rechargeVerifyRequestVO.getThirdRechargeVerifyRequestVO().getChannel());
        thirdRechargeRequestVO.setOrgCode(rechargeVerifyRequestVO.getThirdRechargeVerifyRequestVO().getOrgCode());
        thirdRechargeRequestVO.setToken(rechargeVerifyRequestVO.getThirdRechargeVerifyRequestVO().getToken());
        String userId = validThirdToken(thirdRechargeRequestVO);
        return queryMaxRechargeAmountSubject(rechargeVerifyRequestVO,userId);
    }

    /**
     * 校验充值金额/第三方
     * @param rechargeVerifyRequestVO
     * @param userId
     * @return
     */
    private Result<RechargeVerifyResponseVO> queryMaxRechargeAmountSubject(RechargeVerifyRequestVO rechargeVerifyRequestVO,String userId){
        RechargeVerifyResponseVO responseVO = new RechargeVerifyResponseVO();
        responseVO.setVerifyResult(Boolean.TRUE);
        RechargeMoneyVerifyResponseDTO rechargeMoneyVerifyResponseDTO = rechargeDubboService.getStatisticsRechargeMoneyByUserId(userId);
        GetSimpleUserBankCardResponse serviceResponse = bankCardDubboService.getSimpleUserBankCard(userId,OrgConstant.NIIWOO_ORG_ID);
        PayChannelBankResponseDTO payChannelBankResponseDTO = payChannelBankDubboService.getOptimalPayChannelBankByBankType(serviceResponse.getBankCard().getBankType().getBankTypeId());
        if( null != payChannelBankResponseDTO ){
            if(payChannelBankResponseDTO.getMaxAmountPerTrade().compareTo(rechargeVerifyRequestVO.getAmount()) == -1 ){
                responseVO.setErrorMsg("超过单笔支付限额，您可使用网银充值或调整充值金额");
                responseVO.setVerifyResult(Boolean.FALSE);
                return Result.with(responseVO);
            }else if(payChannelBankResponseDTO.getMaxAmountPerDay().compareTo(rechargeVerifyRequestVO.getAmount().add(rechargeMoneyVerifyResponseDTO.getDayTotalRechargeMoney())) == -1 ){
                BigDecimal daySurplusRecharge = payChannelBankResponseDTO.getMaxAmountPerDay().subtract(rechargeMoneyVerifyResponseDTO.getDayTotalRechargeMoney());
                responseVO.setErrorMsg("您今日最多还可充值"+daySurplusRecharge+"元，您可使用网银充值或调整充值金额");
                responseVO.setVerifyResult(Boolean.FALSE);
                return Result.with(responseVO);
            }else if(payChannelBankResponseDTO.getMaxAmountPerMonth().compareTo(rechargeVerifyRequestVO.getAmount().add(rechargeMoneyVerifyResponseDTO.getMoneyTotalRechargeMoney())) == -1){
                BigDecimal monthSurplusRecharge = payChannelBankResponseDTO.getMaxAmountPerMonth().subtract(rechargeMoneyVerifyResponseDTO.getMoneyTotalRechargeMoney());
                responseVO.setErrorMsg("您当月最多还可充值"+monthSurplusRecharge+"元，您可使用网银充值或调整充值金额");
                responseVO.setVerifyResult(Boolean.FALSE);
                return Result.with(responseVO);
            }
        }else{
            log.info("用户:{},绑卡:{},渠道银行对应表没有记录",userId,JSON.toJSONString(serviceResponse));
        }
        return Result.with(responseVO);
    }

    @PostMapping("/reQueryRecharge")
    @ApiOperation("单笔充值存管查询：成功-补单，失败-不处理")
    public Result<RechargeQueryResponseVO> reQueryRecharge(@RequestBody RechargeQueryRequestVO requestVO){
        RechargeQueryResponseVO responseVO = new RechargeQueryResponseVO();
        RechargeQueryResponseDTO rechargeQueryResponseDTO = rechargeDubboService.queryRechargeCompensation(requestVO.getOrderId());
        BeanUtils.copyProperties(rechargeQueryResponseDTO,responseVO);
        return Result.with(responseVO);
    }
}
